package com.pigotech.ptwo.utils;

/**
 * Created by ghb on 2018/3/15.
 */

public class UtilMath {
    /**
     * 解析字节中每一位为0,1 <br>
     * Integer.toBinaryString(i)</br>
     *
     * @param b
     * @return int[8] --- > 0 -- 8 低位到高位 int[]{1, 0, 0, 0, 0, 0, 0, 0} 代表 1
     */
    public static int[] checkBit(byte b) {
        int[] result = new int[8];
        byte check = 0x01;
        for (int i = 0; i < 8; i++) {
            if ((b & check) == 0) {
                result[i] = 0;
            } else {
                result[i] = 1;
            }
            check = (byte) (check << 1);
        }
        return result;
    }

    /**
     * 8位 0-1 换算成int类型
     *
     * @param bs
     * @return
     */
    public static int getInt(int[] bs) {
        int result = 0;
        for (int i = 0; i < bs.length; i++) {
            if (bs[i] == 1) {
                result += fact(2, i);
            }
        }
        return result;
    }

    /**
     * 获取byte代表的无符号int型
     *
     * @param b
     * @return
     */
    public static int getInt(byte b) {
        int[] bytes = checkBit(b);
        int result = 0;
        for (int i = 0; i < 8; i++) {
            result += bytes[i] * fact(2, i);
        }
        return result;
    }

    /**
     * 阶乘
     *
     * @param num
     * @param count
     * @return
     */
    public static int fact(int num, int count) {
        int result = 1;
        for (int i = 0; i < count; i++) {
            result *= num;
        }
        return result;
    }

    /**
     * 将int型转化成byte[2]，高位在前低位在后
     *
     * @param b
     * @return
     */
    public static byte[] getByte(short num) {
        byte[] result = new byte[2];
        result[0] = (byte) (num >> 8);
        result[1] = (byte) num;
        return result;
    }

    public static byte[] getByte(int num) {
        byte[] result = new byte[4];
        result[0] = (byte) (num >> 24);
        result[1] = (byte) (num >> 16);
        result[2] = (byte) (num >> 8);
        result[3] = (byte) num;
        return result;
    }

    /**
     * 从高低位byte中获取int
     *
     * @param highByte
     *            高位字节
     * @param lowByte
     *            低位字节
     * @return
     */
    public static short getShort(byte highByte, byte lowByte) {
        short result = 0;
        int highnum = UtilMath.getInt(highByte);
        int lownum = UtilMath.getInt(lowByte);
        result = (short) ((highnum << 8) + lownum);
        return result;
    }

    /**
     * 将大端字节数组转为int
     * @param bytes
     * @return
     */
    public static int bigEndianInt(byte[] bytes) {
        int value = 0;
        for (int i = 0; i < bytes.length; i++) {
            value = (value << 8) + getInt(bytes[i]);
        }
        return value;
    }

    /**
     * 将小端字节数组转为int
     * @param bytes
     * @return
     */
    public static long smallEndianInt(byte[] bytes){
        if(bytes.length < 4) {
            return 0;
        }

        long value = 0;
        for(int i = 3; i >= 0; i--){
            value = (value<<8) + getInt(bytes[i]);
        }
        return value;
    }

    /**
     * 将大端字节数组转为long
     * @param bytes
     * @return
     */
    public static long bigEndianLong(byte[] bytes){
        long value = 0;
        for (int i = 0; i < bytes.length; i++) {
            value = (value << 8) + getInt(bytes[i]);
        }
        return value;
    }


    /**
     * 获得无符号的short，对应的字节数组
     *
     * @param i java没有无符号，所有用int表示
     * @return
     */
    public static byte[] nsShortToByteArr(int i) {
        byte[] value = new byte[2];
        value[1] = (byte) i;
        value[0] = (byte) (i >> 8);
        return value;
    }

    /**
     * 获得无符号的int，对应的字节数组
     *
     * @param i java没有无符号，所有用long表示
     * @return
     */
    public static byte[] nsIntToByteArr(long i) {
        byte[] value = new byte[4];
        value[3] = (byte) i;
        value[2] = (byte) (i >> 8);
        value[1] = (byte) (i >> 16);
        value[0] = (byte) (i >> 24);
        return value;
    }
}
